parser grammar CParser;

options {
  language = Java;
  tokenVocab = CLexer;
  backtrack = true;
  ASTLabelType = MiArbol;
  output = AST;
}

tokens {
  LISTA_CODC;
  LISTA_CONDARIT;
}

@header {

  package practpl.diez;
}

@members {
  
    private ArrayList<RecognitionException> errors = new ArrayList<RecognitionException>();
    public ArrayList<RecognitionException> getErrors() {
       return errors;
    }
    @Override
    public void reportError (RecognitionException e) {
       String msg = getErrorMessage(e, getTokenNames());
       System.err.println(msg);
       errors.add(e);
    }   
  
}

entrada : (codigoc)* -> ^(LISTA_CODC (codigoc)*);

codigoc
: declaracion 
| main 
| funcion
;

declaracion 
: tipodedato^ IDENT (COMA! IDENT)* SEPARADOR!
;

asignacion
: IDENT IGUAL^ (FLOAT | NUMERO | IDENT | operadores)+ SEPARADOR!
;

main
:
VOID^ IDENT PARENTA! PARENTC! bloque;

funcion
:
tipodedato^ IDENT PARENTA declaracion? PARENTC bloque
;

llamadafuncion
: IDENT^ PARENTA PARENTC SEPARADOR!
;
                  
sentenciaif
: IF^ PARENTA condicion PARENTC (bloque | sentencias)
(ELSE^ (bloque | sentencias))?
;

cond_aritmetico
: si entonces si_no -> ^(LISTA_CONDARIT si entonces si_no)
;
  
si
: IDENT comparadores^ (IDENT|NUMERO)
;
  
entonces
: QUESTION^ (IDENT|NUMERO) 
;

si_no
: DOSPUNTOS^ (IDENT|NUMERO) SEPARADOR!
;

buclewhile
: WHILE^ PARENTA condicion PARENTC bloque;

condicion: (NUMERO|IDENT|operadores)* comparadores^ (NUMERO|IDENT|operadores)*
;

bloque
: LLAVEA sentencias* LLAVEC
;

sentencias
: buclewhile
| sentenciaif
| declaracion
| asignacion
| funcion
| llamadafuncion
| cond_aritmetico
| BREAK SEPARADOR
;

tipodedato
: VOID 
| INT
| FLOAT
| CHAR
;

operadores
: MAS
| MENOS
| MULT
| DIV
;

comparadores
: MAYOR
| MENOR
| MAYORIGUAL
| MENORIGUAL
| COMPARA
| DISTINTO
;